const router = require('koa-router')();
const multer = require('koa-multer');
const moment = require('moment');
const {GridFsStorage} = require('multer-gridfs-storage');
const utils = require('../lib/utils');
const _ = require('lodash');

let seq = 0;

const storage = new GridFsStorage({
    db: mongodb,
    file: async function(req, file){
        let prefix = file.fieldname;
        let date = moment().format('YYMMDDhhmmss');
        let suffix = seq++;
        let subIndex = file.originalname.lastIndexOf('.') + 1;
        let format = file.originalname.substr(subIndex);
        return {
            filename: `${prefix}_${date}_${suffix}.${format}`,
            bucketName : 'media', //default: fs,
            aliases: file.originalname
        }
    }
});

const gridFs = multer({storage});

// const diskStorage = multer.diskStorage({
//     destination: function (req, file, cb) {
//         cb(null, uploadPath)
//     },
//     filename: function (req, file, cb) {
//         let prefix = file.fieldname;
//         let date = moment().format('YYMMDDhhmmss');
//         let suffix = seq++;
//         let subIndex = file.originalname.lastIndexOf('.') + 1;
//         let format = file.originalname.substr(subIndex);
//
//         cb(null, `${prefix}_${date}_${suffix}.${format}`);
//     }
// });
//
// let uploadDisk = multer({
//     storage : diskStorage
// });

/**
 * 单上传媒体文件接口
 */
router.post('/media', gridFs.single('file'), httpResult.resp(async ctx => {
    let file = ctx.req.file;
    log.debug(file);
    return file;
}));

/**
 * 号码文件上传接口
 */
router.post('/mobiles', gridFs.single('file'), httpResult.resp(async ctx => {
    let file = ctx.req.file;
    // log.debug(file);
    let result = file.originalname.match(/\.(.*)$/);
    let fileType = result && result[1];

    let inputStream = gfs.createReadStream({_id : file.id});
    let numberList = [];

    switch(fileType){
        case 'csv':
        case 'txt': {
            let fileContent = await streamToString(inputStream);
            numberList = fileContent.split('\n');
            break;
        }
        case 'xlsx':
        case 'xls': {break;}
        default : {
            ctx.assert(false, 'unsupported file type: ' + fileType)
        }
    }

    let resp = utils.getMobilesBriefStat(numberList);
    resp.file = file;

    return resp;
}));

/**
 * 号码文件上传接口
 */
router.post('/contact', gridFs.single('file'), httpResult.resp(async ctx => {
    let file = ctx.req.file;
    // log.debug(file);
    let result = file.originalname.match(/\.(.*)$/);
    let fileType = result && result[1];

    let inputStream = gfs.createReadStream({_id : file.id});
    let xlsResult = {};

    switch(fileType){
        case 'xlsx':
        case 'xls': {
            file.buffer = await streamToBuffer(inputStream);
            xlsResult = utils.commonXlsxFileParser(file);
            break;
            }
        default : {
            ctx.assert(false, 'unsupported file type: ' + fileType)
        }
    }
    ctx.assert(xlsResult.code === 0, xlsResult.msg);

    let {customer_chain, customer_name, _id} = ctx.session.admin;

    let allTags = await models.tag.find({status : 1, customer_chain : new RegExp(`^${customer_chain}`)}).lean();
    let tagMap = _.keyBy(allTags, 'name');

    let importList = [];
    for(let r of xlsResult.data){
        let tags = [];
        for(let name of (r['标签'] || '').split(',')){
            if (!name){
                continue;
            }
            if(!tagMap[name]){
                let tag = await models.tag.create({name, type : 'contact', customer_chain, creator : _id, create_time : new Date()});
                tagMap[tag.name] = tag;
            }
            tags.push(tagMap[name]._id.toString());//这个toString不能省略，不然会出现计数不准的问题。
        }
        importList.push({
            name : r['姓名'],
            mobile : r['手机号'],
            gender : constant[r['性别']],
            birthday : r['生日'] ? moment(r['生日']) : undefined,
            comment : r['备注'],
            tags : tags
        })
    }

    let resp = {total : importList.length, success : 0, message : '导入成功'};
    try{
        await models.contact.insertMany(importList);
        resp.success = resp.total;
    }catch(err){
        resp.success = err.insertedDocs.length;
        resp.message = err.message
    }
    return resp;
}));

function streamToBuffer (stream) {
    const chunks = []
    return new Promise((resolve, reject) => {
        stream.on('data', chunk => chunks.push(chunk))
        stream.on('error', reject)
        stream.on('end', () => resolve(Buffer.concat(chunks)))
    })
}
function streamToString (stream) {
    const chunks = []
    return new Promise((resolve, reject) => {
        stream.on('data', chunk => chunks.push(chunk))
        stream.on('error', reject)
        stream.on('end', () => resolve(Buffer.concat(chunks).toString('utf8')))
    })
}

router.get('/media', async (ctx, next) => {
    let _id = ctx.query.id;
    ctx.assert(_id, '未提交文件id');
    let fileMeta = await gfs.files.findOne({_id: gfs.tryParseObjectId(_id)});
    ctx.assert(fileMeta, '文件不存在');

    let readstream = gfs.createReadStream({_id});
    // ctx.attachment(fileMeta.filename);
    ctx.type = fileMeta.contentType;
    ctx.body = readstream;
});

module.exports = router;

/**
 {
   fieldname: 'file',
   originalname: 'mobileNumbers.txt',
   encoding: '7bit',
   mimetype: 'text/plain',
   id: 621742918aa4473342dc864b,
   filename: 'file_220224043217_0.txt',
   metadata: null,
   bucketName: 'media',
   chunkSize: 261120,
   size: 120,
   md5: '2a22c83df14584df3cd16676bdf37fa9',
   uploadDate: 2022-02-24T08:32:17.347Z,
   contentType: 'text/plain'
 }
 */
